namespace SimpleWebServices.Web.UI.Html.Elements
{
    using System;
    using System.Xml;
    using System.Xml.Serialization;
    using SimpleWebServices;
    using Xunit;

    public sealed class MetaFacts
    {
        [Fact]
        public void typedef()
        {
            Assert.True(new ObjectExpectations<Meta>()
                .DerivesFrom<object>()
                .IsConcreteClass()
                .IsUnsealed()
                .HasDefaultConstructor()
                .Implements<IXmlSerializable>()
                .XmlRoot("meta")
                .Result);
        }

        [Fact]
        public void deserialize()
        {
            Meta expected = new Meta
            {
                HttpEquivalent = "date",
                Name = "DC.date",
                Content = "1999-12-31",
                Scheme = "W3CDTF"
            };

            string xml = "<meta http-equiv='date' name='DC.date' content='1999-12-31' scheme='W3CDTF' />";
            Meta actual = xml.Deserialize<Meta>();

            Assert.Equal<Meta>(expected, actual);
        }

        [Fact]
        public void deserializeEmpty()
        {
            Assert.NotNull("<meta />".Deserialize<Meta>());
        }

        [Fact]
        public void serialize()
        {
            Meta obj = new Meta
            {
                HttpEquivalent = "date",
                Name = "DC.date",
                Content = "1999-12-31",
                Scheme = "W3CDTF"
            };

            string xpath = "1=count(/meta[@http-equiv='date'][@name='DC.date'][@content='1999-12-31'][@scheme='W3CDTF'])";

            Assert.True((bool)obj.Serialize().CreateNavigator().Evaluate(xpath));
        }

        [Fact]
        public void ctor()
        {
            Assert.NotNull(new Meta());
        }

        [Fact]
        public void prop_HttpEquivalent()
        {
            Assert.True(new PropertyExpectations(typeof(Meta).GetProperty("HttpEquivalent"))
                .IsAutoProperty<Name>()
                .Result);
        }

        [Fact]
        public void prop_Name()
        {
            Assert.True(new PropertyExpectations(typeof(Meta).GetProperty("Name"))
                .IsAutoProperty<Name>()
                .Result);
        }

        [Fact]
        public void prop_Content()
        {
            Assert.True(new PropertyExpectations(typeof(Meta).GetProperty("Content"))
                .IsAutoProperty<string>()
                .Result);
        }

        [Fact]
        public void prop_Scheme()
        {
            Assert.True(new PropertyExpectations(typeof(Meta).GetProperty("Scheme"))
                .IsAutoProperty<string>()
                .Result);
        }

        [Fact]
        public void opEquality_Meta_Meta()
        {
            Meta obj = new Meta
            {
                HttpEquivalent = "content-language",
                Content = "en"
            };

            Meta comparand = new Meta
            {
                HttpEquivalent = "content-language",
                Content = "en"
            };

            Assert.True(obj == comparand);
        }

        [Fact]
        public void opEquality_Meta_MetaDiffers()
        {
            Meta obj = new Meta
            {
                HttpEquivalent = "content-language",
                Content = "en"
            };

            Meta comparand = new Meta
            {
                Name = "DC.date",
                Content = "1999-12-31",
                Scheme = "W3CDTF"
            };

            Assert.False(obj == comparand);
        }

        [Fact]
        public void opEquality_Meta_MetaSame()
        {
            Meta obj = new Meta
            {
                HttpEquivalent = "content-language",
                Content = "en"
            };

            Meta comparand = obj;

            Assert.True(obj == comparand);
        }

        [Fact]
        public void opEquality_MetaNull_Meta()
        {
            Meta obj = null;

            Meta comparand = new Meta
            {
                HttpEquivalent = "content-language",
                Content = "en"
            };

            Assert.False(obj == comparand);
        }

        [Fact]
        public void opEquality_Meta_MetaNull()
        {
            Meta obj = new Meta
            {
                HttpEquivalent = "content-language",
                Content = "en"
            };

            Meta comparand = null;

            Assert.False(obj == comparand);
        }

        [Fact]
        public void opInequality_Meta_Meta()
        {
            Meta obj = new Meta
            {
                HttpEquivalent = "content-language",
                Content = "en"
            };

            Meta comparand = new Meta
            {
                HttpEquivalent = "content-language",
                Content = "en"
            };

            Assert.False(obj != comparand);
        }

        [Fact]
        public void opInequality_Meta_MetaDiffers()
        {
            Meta obj = new Meta
            {
                HttpEquivalent = "content-language",
                Content = "en"
            };

            Meta comparand = new Meta
            {
                Name = "DC.date",
                Content = "1999-12-31",
                Scheme = "W3CDTF"
            };

            Assert.True(obj != comparand);
        }

        [Fact]
        public void opInequality_Meta_MetaSame()
        {
            Meta obj = new Meta
            {
                HttpEquivalent = "content-language",
                Content = "en"
            };

            Meta comparand = obj;

            Assert.False(obj != comparand);
        }

        [Fact]
        public void opInequality_MetaNull_Meta()
        {
            Meta obj = null;

            Meta comparand = new Meta
            {
                HttpEquivalent = "content-language",
                Content = "en"
            };

            Assert.True(obj != comparand);
        }

        [Fact]
        public void opInequality_Meta_MetaNull()
        {
            Meta obj = new Meta
            {
                HttpEquivalent = "content-language",
                Content = "en"
            };

            Meta comparand = null;

            Assert.True(obj != comparand);
        }

        [Fact]
        public void op_GetHashCode()
        {
            Meta obj = new Meta
            {
                HttpEquivalent = "content-language",
                Content = "en"
            };

            int expected = obj.ToString().GetHashCode();
            int actual = obj.GetHashCode();

            Assert.Equal<int>(expected, actual);
        }

        [Fact]
        public void op_Equals_object()
        {
            Meta obj = new Meta
            {
                HttpEquivalent = "content-language",
                Content = "en"
            };

            Meta comparand = new Meta
            {
                HttpEquivalent = "content-language",
                Content = "en"
            };

            Assert.True(obj.Equals(comparand as object));
        }

        [Fact]
        public void op_Equals_objectDiffer()
        {
            Meta obj = new Meta
            {
                HttpEquivalent = "content-language",
                Content = "en"
            };

            Meta comparand = new Meta
            {
                Name = "DC.date",
                Content = "1999-12-31",
                Scheme = "W3CDTF"
            };

            Assert.False(obj.Equals(comparand as object));
        }

        [Fact]
        public void op_Equals_objectSame()
        {
            Meta obj = new Meta
            {
                HttpEquivalent = "content-language",
                Content = "en"
            };

            Assert.True(obj.Equals(obj as object));
        }

        [Fact]
        public void op_Equals_objectNull()
        {
            Assert.False(new Meta().Equals(null as object));
        }

        [Fact]
        public void op_Equals_objectString()
        {
            Assert.False(new Meta().Equals(string.Empty as object));
        }
        
        [Fact]
        public void op_GetSchema()
        {
            Assert.Throws<NotSupportedException>(() => (new Meta() as IXmlSerializable).GetSchema());
        }

        [Fact]
        public void op_ReadXml_XmlReaderNull()
        {
            Assert.Throws<ArgumentNullException>(() => (new Meta() as IXmlSerializable).ReadXml(null as XmlReader));
        }

        [Fact]
        public void op_WriteXml_XmlWriterNull()
        {
            Assert.Throws<ArgumentNullException>(() => (new Meta() as IXmlSerializable).WriteXml(null as XmlWriter));
        }
    }
}